import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
import subprocess
import threading
import sys
import os
import json


class CMDExecutorApp:
    def __init__(self, root):
        self.root = root
        root.title("急救助手打包工具")
        root.geometry("800x600")

        self.gradle_file_path = "app/build.gradle"
        self.gradle_copy_file_path = "app/build_copy.gradle"
        self.mcs_file_path = "mcs-services.json"
        self.mcs_copy_file_path = "mcs-services_copy.json"

        self.package_types = [
            {"name": "急救助手", "product": "jjzs", "flavors": "Jjzs", "package_name": "com.pj.fais6",
             "honor_app_id": "104467352"},
            {"name": "车载助手", "product": "czzs", "flavors": "Czzs", "package_name": "com.pj.czzs",
             "honor_app_id": "104487345"},
            {"name": "司机端", "product": "sjd", "flavors": "Sjd", "package_name": "com.pj.sjd",
             "honor_app_id": "104487349"},
            {"name": "医生端", "product": "ysd", "flavors": "Ysd", "package_name": "com.pj.ysd",
             "honor_app_id": "104487346"},
            {"name": "专家端", "product": "zjd", "flavors": "Zjd", "package_name": "com.pj.zjd",
             "honor_app_id": "104487352"}
        ]
        # 新增：定义复选框选项对象数组
        self.checkbox_options = [
            {"name": "视频会诊(TRTC)", "module": "trtc"},
            {"name": "健康平台对接(雅安)", "module": "yaan_jkpt"},
            {"name": "院内his对接(雅安)", "module": "yaan_his"}
        ]
        self.selected_package_type = tk.StringVar()
        self.selected_product = None
        self.selected_modules = []  # 修改：存储选中的module值

        self.setup_style()
        self.create_widgets()
        self.process = None

    def setup_style(self):
        style = ttk.Style()
        style.configure("TLabel", padding=6, font=('微软雅黑', 10))
        style.configure("TButton", font=('微软雅黑', 10))
        style.configure("TEntry", font=('微软雅黑', 10))

    def create_widgets(self):
        # 修改：下拉选择框区域
        combobox_frame = ttk.Frame(self.root)
        combobox_frame.pack(pady=5, padx=10, fill=tk.X)

        ttk.Label(combobox_frame, text="打包类型:").pack(side=tk.LEFT)
        # 只使用name属性作为显示值
        package_names = [pkg["name"] for pkg in self.package_types]
        self.package_type_combo = ttk.Combobox(
            combobox_frame,
            textvariable=self.selected_package_type,
            values=package_names,
            state='readonly',
            width=20
        )
        self.package_type_combo.pack(side=tk.LEFT, padx=5)
        self.package_type_combo.bind('<<ComboboxSelected>>', self.on_package_type_selected)

        # 修改：复选框区域
        checkbox_frame = ttk.Frame(self.root)
        checkbox_frame.pack(pady=5, padx=10, fill=tk.X)

        self.checkboxes = {}
        for option in self.checkbox_options:
            var = tk.BooleanVar()
            cb = ttk.Checkbutton(
                checkbox_frame,
                text=option["name"],
                variable=var,
                command=lambda opt=option, v=var: self.on_checkbox_click(opt, v)
            )
            cb.pack(side=tk.LEFT, padx=5)
            self.checkboxes[option["name"]] = var

        # 命令输入区
        input_frame = ttk.Frame(self.root)
        input_frame.pack(pady=10, padx=10, fill=tk.X)

        # ttk.Label(input_frame, text="输入命令:").pack(side=tk.LEFT)
        # self.cmd_entry = ttk.Entry(input_frame, width=50)
        # self.cmd_entry.pack(side=tk.LEFT, padx=5, expand=True, fill=tk.X)
        # self.cmd_entry.bind("<Return>", self.execute_command)

        self.execute_btn = ttk.Button(
            input_frame,
            text="开始打包",
            command=self.execute_command
        )
        self.execute_btn.pack(side=tk.LEFT, padx=5)

        # 输出显示区
        output_frame = ttk.Frame(self.root)
        output_frame.pack(pady=10, padx=10, fill=tk.BOTH, expand=True)

        self.output_area = scrolledtext.ScrolledText(
            output_frame,
            wrap=tk.WORD,
            font=('Consolas', 10),
            state='normal'
        )
        self.output_area.pack(fill=tk.BOTH, expand=True)

        # 状态栏
        self.status_bar = ttk.Label(
            self.root,
            text="就绪",
            relief=tk.SUNKEN
        )
        self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)

    def execute_command(self, event=None):
        if self.selected_product is None:
            messagebox.showwarning("提示", "请选择打包类型！", parent=self.root)
            return
        self.build_mcs_file()
        self.build_temp_gradle_file()
        self.toggle_ui_state(False)
        self.update_status("正在打包...")
        self.output_area.delete(1.0, tk.END)
        self.append_output('\n开始构建APK...\n')
        cmd = f'gradlew assemble{self.selected_product["flavors"]}Release'

        threading.Thread(
            target=self.run_command,
            args=(cmd,),
            daemon=True
        ).start()

    def run_command(self, cmd):
        try:
            self.process = subprocess.Popen(
                cmd,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                encoding='gbk',
                bufsize=1,
                universal_newlines=True
            )

            while True:
                line = self.process.stdout.readline()
                if not line and self.process.poll() is not None:
                    break
                if line:
                    self.append_output(line)

            if self.process.returncode != 0:
                self.append_output(f"\n打包失败，返回码：{self.process.returncode}\n")

        except Exception as e:
            self.append_output(f"发生错误：{str(e)}\n")
        finally:
            self.recover_mcs_file()
            self.recover_gradle_file()
            self.append_output(
                f'\n打包完成,apk文件路径{os.getcwd()}\\app\\build\\outputs\\apk\\{self.selected_product["product"]}\\release\\')
            self.command_finished()

    def append_output(self, text):
        self.root.after(0, self._safe_append, text)

    def _safe_append(self, text):
        self.output_area.configure(state='normal')
        self.output_area.insert(tk.END, text)
        self.output_area.see(tk.END)
        self.output_area.configure(state='disabled')

    def command_finished(self):
        self.root.after(0, self._safe_finish)

    def _safe_finish(self):
        self.toggle_ui_state(True)
        self.update_status("命令执行完成")

    def toggle_ui_state(self, enabled):
        state = tk.NORMAL if enabled else tk.DISABLED
        self.execute_btn.config(state=state)
        self.package_type_combo.config(state=state)

    def update_status(self, message):
        self.status_bar.config(text=message)

    # 修改：复选框点击事件处理
    def on_checkbox_click(self, option, var):
        if var.get():
            if option["module"] not in self.selected_modules:
                self.selected_modules.append(option["module"])
        else:
            if option["module"] in self.selected_modules:
                self.selected_modules.remove(option["module"])
        print(f"Selected modules: {self.selected_modules}")  # 可以根据需要修改或删除此打印语句

    # 修改：下拉框选择事件处理
    def on_package_type_selected(self, event):
        selected_name = self.selected_package_type.get()
        # 根据选中的name找到对应的product
        for pkg in self.package_types:
            if pkg["name"] == selected_name:
                self.selected_product = pkg
                break

    # 读取build.gradle文件内容并写入临时文件
    def build_temp_gradle_file(self):
        product_name = self.selected_product['product']
        modules = self.selected_modules
        try:
            self.append_output(f'\n正在备份{self.gradle_file_path}文件...')
            # 备份原始build.gradle文件
            with open(self.gradle_file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                # 写入临时文件
                with open(self.gradle_copy_file_path, 'w', encoding='utf-8') as temp_file:
                    temp_file.write(content)
            self.append_output(f'\n{self.gradle_file_path}文件备份完成..')
            self.append_output(
                f'\n正在构建新的gradle文件,打包产品【{self.selected_product["name"]}】，打包模块【{modules}】')
            # 修改build.gradle文件的内容
            with open(self.gradle_file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                # 构建新的gradle文件内容
                add_content = ['annotationProcessor libDependencies.glideCompiler']  # 新增的依赖
                if len(modules) > 0:
                    for module in modules:
                        add_content.append(f"\t{product_name}Implementation project(':{module}')")

                if len(add_content) > 1:
                    datas = '\n'.join(add_content)
                    content = content.replace('annotationProcessor libDependencies.glideCompiler', datas)
            with open(self.gradle_file_path, 'w', encoding='utf-8') as file:
                file.write(content)

            self.append_output('\ngradle文件构建完成...')
        except FileNotFoundError:
            self.append_output(f"未找到 {self.gradle_file_path} 文件")
        except Exception as e:
            self.append_output(f"操作文件时发生错误：{str(e)}")

    def build_mcs_file(self):
        """读取msc-services.json文件内容并转换为字典"""
        try:
            self.append_output(f'\n正在备份{self.mcs_copy_file_path}文件...')
            m_package_name = self.selected_product['package_name']
            m_app_id = self.selected_product['honor_app_id']
            with open(self.mcs_file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                msc_data = json.loads(content)
                with open(self.mcs_copy_file_path, 'w', encoding='utf-8') as temp_file:
                    temp_file.write(content)
                print(msc_data['app_id'])
            self.append_output(f'\n正在构建新的{self.mcs_file_path}文件...')
            with open(self.mcs_file_path, 'w', encoding='utf-8') as file1:
                msc_data['app_id'] = m_app_id
                msc_data['package_name'] = m_package_name
                json.dump(msc_data, file1, ensure_ascii=False)
            self.append_output(f'\n新的{self.mcs_file_path}文件构建完成...')
        except FileNotFoundError:
            self.append_output(f"\n未找到 {self.mcs_file_path} 文件")
        except json.JSONDecodeError:
            self.append_output(f"\n{self.mcs_file_path} 文件格式错误")
        except Exception as e:
            self.append_output(f"\n读取文件时发生错误：{str(e)}")

    def recover_gradle_file(self):
        """恢复build.gradle文件"""
        try:
            self.append_output(f'\n正在恢复{self.gradle_file_path}文件...')
            with open(self.gradle_copy_file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                with open(self.gradle_file_path, 'w', encoding='utf-8') as temp_file:
                    temp_file.write(content)
            self.append_output(f'\n{self.gradle_file_path}文件恢复完成...')
            if os.path.exists(self.gradle_copy_file_path):
                os.remove(self.gradle_copy_file_path)
                self.append_output(f'\n{self.gradle_copy_file_path}文件已删除')
        except FileNotFoundError as e:
            self.append_output(e)
        except Exception as e:
            self.append_output(f"操作文件时发生错误：{str(e)}")

    def recover_mcs_file(self):
        """恢复build.gradle文件"""
        try:
            self.append_output(f'\n正在恢复{self.mcs_file_path}文件...')
            with open(self.mcs_copy_file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                with open(self.mcs_file_path, 'w', encoding='utf-8') as temp_file:
                    temp_file.write(content)
            self.append_output(f'\n{self.mcs_file_path}文件恢复完成...')
            if os.path.exists(self.mcs_copy_file_path):
                os.remove(self.mcs_copy_file_path)
                self.append_output(f'\n{self.mcs_copy_file_path}文件已删除')
        except FileNotFoundError as e:
            self.append_output(e)
        except Exception as e:
            self.append_output(f"操作文件时发生错误：{str(e)}")


if __name__ == "__main__":
    root = tk.Tk()
    app = CMDExecutorApp(root)
    root.mainloop()
